package com.demo.mutilThread;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 添加poll
 */
public class BlockingQqeueAddPoll<T> {
    //1 任务队列
    private Deque<T> queue = new ArrayDeque<T>(5);
    //2 锁
    private ReentrantLock lock = new ReentrantLock();
    //3 生产者条件变量
    private Condition fullWaitSet = lock.newCondition();
    //4 消费者条件变量
    private Condition emptyWaitSet = lock.newCondition();
    //5 容量
    private int capcity;

    //带超时的阻塞获取
    public T poll(long timeout, TimeUnit unit) {
        lock.lock();
        try {
            //将timeOunt统一转换为纳秒
            long nanos = unit.toNanos(timeout);
            while (queue.isEmpty()) {
                //nanos返回的是剩余时间
                if (nanos <= 0) {
                    return null;
                }
                try {
                    nanos = emptyWaitSet.awaitNanos(nanos);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            T t = queue.removeFirst();
            fullWaitSet.signal();
            return t;
        } finally {
            lock.unlock();
        }
    }

    //阻塞获取
//    public T take() {
//        lock.lock();
//        try {
//            while (queue.isEmpty()) {
//                try {
//                    emptyWaitSet.await();
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                // fullWaitSet.signal();
//            }
//            T t = queue.removeFirst();
//            fullWaitSet.signal();
//            return t;
//        } finally {
//            lock.unlock();
//        }
//    }

    //阻塞添加
    public void put(T element) {
        lock.lock();
        try {
            while (queue.size() == capcity) {
                try {
                    fullWaitSet.await();
                    //唤醒队列
                    emptyWaitSet.signal();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            queue.addLast(element);
        } finally {
            lock.unlock();
        }
    }

    //获取大小
    public int size() {
        lock.lock();
        try {
            return queue.size();
        } finally {
            lock.unlock();
        }
    }
}
